#include "PAP_defs.h"
#include "Fixed_Point_Math.h"

#define ADC_10_BIT_ZERO_OFFSET 512  //DEFAULT ZERO OFFSET

#define ADC_10_BIT_MAX +103 //DEFAULT MAXIMUM VALID VALUE FOR 10BIT ACCELEROMETER READ OVER ZERO OFFSET
#define ADC_10_BIT_MIN -103 //MINUMUM ...123

#define ADC_10_2_8_BITS_CONVERSION 384 //OFFSET FOR CONVERSION FROM 10 TO 8 BIT (512 - 128ADC_10_2_8_BITS_CONVERSION)

#define ADC_8_BIT_MAX (128 + 103)
#define ADC_8_BIT_MIN (128 - 103)

#define ADC_8_BIT_MAX_AFTER_FILTER (128 + 97)
#define ADC_8_BIT_MIN_AFTER_FILTER (128 - 97)

#define SENSOR_ACCEL_1G 136

#define ADC_MAX_CALIBRATION_OFFSET 45	//Maximum value that accelerometer should have for a valid calibration point
										//Masimum deviation of accelerometer is equal to 30 steps. !5 extra steps are added

#define ADC_MAX_CAL_OFFSET ( ADC_10_BIT_ZERO_OFFSET + ADC_MAX_CALIBRATION_OFFSET )
#define ADC_MIN_CAL_OFFSET ( ADC_10_BIT_ZERO_OFFSET - ADC_MAX_CALIBRATION_OFFSET )
				
/*This macro multiplies two 16 bit values saved in an uUN16 variable and 
returns the multiplication result divided by 2^15:	rslt=(d1*d2)/(2^15).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: uUN16, rslt: unsigned short
#define mMul16x16to32Q15(d1,d2,rslt)															\
do {										 													\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2.bytes.b0);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b0 * d2.bytes.b1) + uUN32tempo.bytes.b1);		\
	u8tempo = uUN32tempo.bytes.b2;																\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2.bytes.b0) + uUN32tempo.bytes.b1);			\
	uUN32tempo.shorts.s1 = (uint16)(uUN32tempo.bytes.b2 + u8tempo + (d1.bytes.b1*d2.bytes.b1));	\
	uUN32tempo.shorts.s1 = uUN32tempo.shorts.s1<<1;												\
	if(uUN32tempo.bytes.b1&0x80)                                                                \
	{                                                                                           \
	    uUN32tempo.bytes.b2++;                                                                  \
	}                                                                                           \
	rslt=uUN32tempo.shorts.s1;																	\
} while(0)

/*This macro multiplies two 16 bit values saved in an uUN16 variable and 
returns the multiplication result divided by 2^14:	rslt=(d1*d2)/(2^14).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: uUN16, rslt: unsigned short
#define mMul16x16to32Q14(d1,d2,rslt)															\
do {										 													\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2.bytes.b0);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b0 * d2.bytes.b1) + uUN32tempo.bytes.b1);		\
	u8tempo = uUN32tempo.bytes.b2;																\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2.bytes.b0) + uUN32tempo.bytes.b1);			\
	uUN32tempo.shorts.s1 = (uint16)(uUN32tempo.bytes.b2 + u8tempo + (d1.bytes.b1*d2.bytes.b1));	\
	uUN32tempo.l = uUN32tempo.l<<2;												                \
	rslt=uUN32tempo.shorts.s1;																	\
} while(0)


/*This macro multiplies one 16 bit saved in an uUN16 variable by an 8 bit saved
 in a unsigned char variable and retunrs the multiplication result divideb by 
 2^15 and in an un short variable:	rslt=(d1*d2)/(2^15).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: u8, rslt: unsigned short
#define mMul16x8to32Q15(d1,d2,rslt)														\
do {										 											\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2)+uUN32tempo.bytes.b1);				\
	uUN32tempo.bytes.b3 = 0;															\
	uUN32tempo.shorts.s1 = uUN32tempo.shorts.s1<<1;										\
	if(uUN32tempo.bytes.b1&0x80) { uUN32tempo.bytes.b2++; } 							\
	rslt=uUN32tempo.shorts.s1;															\
} while(0)																						    


/*This macro multiplies one 16 bit saved in an uUN16 variable by an 8 bit saved
 in a unsigned char variable and retunrs the multiplication result divideb by 
 2^14 and in an un short variable:	rslt=(d1*d2)/(2^14).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: u8, rslt: unsigned short
#define mMul16x8to32Q14(d1,d2,rslt)														\
do {										 											\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2)+uUN32tempo.bytes.b1);				\
	uUN32tempo.bytes.b3 = 0;															\
	uUN32tempo.l = uUN32tempo.l<<2;             										\
	rslt=uUN32tempo.shorts.s1;															\
} while(0)																						    


/*This macro multiplies two 16 bit values saved in an uUN16 variable and 
returns the multiplication result divided by 2^20 and in an 8 bit variable:	
rslt = (d1 * d2) / (2^20).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: uUN16, rslt: unsigned char
#define mMul16x16to32Q20(d1,d2,rslt)															\
do {										 													\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2.bytes.b0);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b0 * d2.bytes.b1) + uUN32tempo.bytes.b1);		\
	u8tempo = uUN32tempo.bytes.b2;																\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2.bytes.b0)+uUN32tempo.bytes.b1);			\
	uUN32tempo.shorts.s1 = (uint16)(uUN32tempo.bytes.b2+u8tempo+(d1.bytes.b1*d2.bytes.b1));		\
	uUN32tempo.shorts.s1 = uUN32tempo.shorts.s1>>4;												\
	if(uUN32tempo.bytes.b3){uUN32tempo.bytes.b2=0xFF;}											\
	rslt=uUN32tempo.bytes.b2;																	\
} while(0)	


/*This macro multiplies two 16 bit values saved in an uUN16 variable and 
returns the multiplication result divided by 2^18 and in an 8 bit variable:	
rslt = (d1 * d2) / (2^18).
The macro needs two variables:
	uUN32 uUN32tempo;
	unsigned char u8tempo;	*/

//d1:uUN16, d2: uUN16, rslt: unsigned char
#define mMul16x16to32Q18(d1,d2,rslt)															\
do {										 													\
	uUN32tempo.shorts.s0 = (uint16)(d1.bytes.b0 * d2.bytes.b0);									\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b0 * d2.bytes.b1) + uUN32tempo.bytes.b1);		\
	u8tempo = uUN32tempo.bytes.b2;																\
	uUN32tempo.shortOf8.s = (uint16)((d1.bytes.b1*d2.bytes.b0)+uUN32tempo.bytes.b1);			\
	uUN32tempo.shorts.s1 = (uint16)(uUN32tempo.bytes.b2+u8tempo+(d1.bytes.b1*d2.bytes.b1));		\
	uUN32tempo.shorts.s1 = uUN32tempo.shorts.s1>>2;												\
	if(uUN32tempo.bytes.b3){uUN32tempo.bytes.b2=0xFF;}											\
	rslt=uUN32tempo.bytes.b2;																	\
} while(0)	


// Prototype definitions

void vfnFilterInit (void);																					    

uint8 u8FilterADCX (uint8 u8input);

uint8 u8FilterADCY (uint8 u8input);

uint8 u8FilterADCZ (uint8 u8input);









